SUBDIRS =	sys \
		suricatasc \
		suricatactl

EXTRA_DIST =	src derive htp \
		.cargo/config.toml.in \
		cbindgen.toml \
		dist/rust-bindings.h \
		dist/htp/htp_rs.h \
		vendor \
		Cargo.toml Cargo.lock \
		derive/Cargo.toml \
		sys \
		sys/Cargo.toml \
		suricatasc \
		suricatactl \
		htp/Cargo.toml

if !DEBUG
RELEASE = --release
endif

if RUST_BUILD_STD
NIGHTLY_ARGS = -Z build-std
endif

if HAVE_JA3
RUST_FEATURES +=	ja3
endif

if HAVE_JA4
RUST_FEATURES +=	ja4
endif

if DEBUG
RUST_FEATURES +=	debug
endif

if DEBUG_VALIDATION
RUST_FEATURES +=	debug-validate
endif

if RUST_CROSS_COMPILE 
RUST_TARGET = --target $(host_triplet)
endif

if HAVE_CYGPATH
CARGO_ENV =	@rustup_home@ \
		CARGO_HOME="$(CARGO_HOME)" \
		CARGO_TARGET_DIR="$(e_rustdir)/target" \
		SURICATA_LUA_SYS_HEADER_DST="$(e_rustdir)/gen"
else
CARGO_ENV =	@rustup_home@ \
		CARGO_HOME="$(CARGO_HOME)" \
		CARGO_TARGET_DIR="$(abs_top_builddir)/rust/target" \
		SURICATA_LUA_SYS_HEADER_DST="$(abs_top_builddir)/rust/gen"
endif

CARGO_ENV +=	LOCALSTATEDIR=$(e_localstatedir)

# To pass specific CFLAGS to Lua.
CARGO_ENV +=	SURICATA_LUA_SYS_CFLAGS="$(SURICATA_LUA_SYS_CFLAGS)"

all-local: Cargo.toml
	mkdir -p $(abs_top_builddir)/rust/gen
	cd $(abs_top_srcdir)/rust && \
		CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)"\
		$(CARGO_ENV) \
		$(CARGO) build $(RELEASE) $(NIGHTLY_ARGS) \
			--features "$(RUST_FEATURES)" $(RUST_TARGET)
	if test -e $(RUST_SURICATA_LIBDIR)/suricata.lib; then \
		cp -a $(RUST_SURICATA_LIBDIR)/suricata.lib \
			$(RUST_SURICATA_LIBDIR)/${RUST_SURICATA_LIBNAME}; \
	fi
	if test -e $(RUST_SURICATA_LIBDIR)/libsuricata.a; then \
		cp -a $(RUST_SURICATA_LIBDIR)/libsuricata.a \
			$(RUST_SURICATA_LIBDIR)/${RUST_SURICATA_LIBNAME}; \
	fi
	$(MAKE) gen/rust-bindings.h
	$(MAKE) gen/htp/htp_rs.h
	if test -e Cargo.lock.in; then \
		cp Cargo.lock Cargo.lock.in; \
	fi

install-exec-local:
	install -d -m 0755 "$(DESTDIR)$(bindir)"
	install -m 0755 $(RUST_SURICATA_LIBDIR)/suricatasc "$(DESTDIR)$(bindir)/suricatasc"
	install -m 0755 $(RUST_SURICATA_LIBDIR)/suricatactl "$(DESTDIR)$(bindir)/suricatactl"

install-library:
	$(MKDIR_P) "$(DESTDIR)$(libdir)"
	$(INSTALL_DATA) $(RUST_SURICATA_LIB) "$(DESTDIR)$(libdir)"

uninstall-local:
	rm -f "$(DESTDIR)$(libdir)/$(RUST_SURICATA_LIBNAME)"
	rm -f "$(DESTDIR)$(bindir)/suricatasc"
	rm -f "$(DESTDIR)$(bindir)/suricatactl"

clean-local:
	rm -rf target gen

distclean-local:
	rm -rf vendor dist

check-bindgen-bindings:
if HAVE_BINDGEN
	if test "$(top_srcdir)" = "$(top_builddir)"; then \
		cp sys/src/sys.rs sys/src/sys.rs.orig; \
		$(MAKE) update-bindings; \
		if diff sys/src/sys.rs sys/src/sys.rs.orig > /dev/null 2>&1; then \
			rm -f sys/src/sys.rs.orig; \
		else \
			echo "WARNING: bindgen bindings may be out of date"; \
		fi \
	else \
		echo "Not checking bindings for out of tree build"; \
	fi
else
	@echo "Unable to check bindgen bindings: bindgen not found"
endif

check:
	cd $(abs_top_srcdir)/rust && \
		$(CARGO_ENV) \
		$(CARGO) test --all $(RELEASE) --features "$(RUST_FEATURES)"
	$(MAKE) check-bindgen-bindings

vendor:
	$(CARGO_ENV) $(CARGO) vendor

update-bindings:
if HAVE_BINDGEN
	$(BINDGEN) \
		-o sys/src/sys.rs.tmp \
		--rust-target 1.68 \
		--no-layout-tests \
		--disable-header-comment \
		--default-enum-style rust \
		--allowlist-type 'AppProto.*' \
		--allowlist-function 'AppProto.*' \
		--allowlist-type 'SC.*' \
		--allowlist-function 'SC.*' \
		--allowlist-var 'SC.*' \
		--opaque-type 'SCConfNode' \
		$(abs_top_srcdir)/src/bindgen.h \
		-- \
		-DHAVE_CONFIG_H -I../src -I../rust/gen $(CPPFLAGS)
	printf "// This file is automatically generated. Do not edit.\n\n" > sys/src/sys.rs
	cat sys/src/sys.rs.tmp >> sys/src/sys.rs
	rm -f sys/src/sys.rs.tmp
	$(CBINDGEN) --quiet --config cbindgen.toml src/jsonbuilder.rs -o gen/jsonbuilder.h
	$(BINDGEN) \
		-o sys/src/jsonbuilder.rs.tmp \
		--rust-target 1.68 \
		--no-layout-tests \
		--disable-header-comment \
		--allowlist-function 'SC.*' \
		gen/jsonbuilder.h \
		-- \
		-DHAVE_CONFIG_H -I../src -I../rust/gen $(CPPFLAGS)
	printf "// This file is automatically generated. Do not edit.\n\n" > sys/src/jsonbuilder.rs
	cat sys/src/jsonbuilder.rs.tmp >> sys/src/jsonbuilder.rs
	rm -f sys/src/jsonbuilder.rs.tmp
else
	@echo "error: bindgen not installed, can't update bindings"
	exit 1
endif

if HAVE_CBINDGEN
gen/rust-bindings.h: $(RUST_SURICATA_LIB) cbindgen.toml
	cd $(abs_top_srcdir)/rust && \
		$(CBINDGEN) --config $(abs_top_srcdir)/rust/cbindgen.toml \
		--quiet --verify --output $(abs_top_builddir)/rust/gen/rust-bindings.h || true
else
gen/rust-bindings.h:
endif

if HAVE_CBINDGEN
gen/htp/htp_rs.h: $(RUST_SURICATA_LIB) htp/cbindgen.toml
	cd $(abs_top_srcdir)/rust/htp && \
		cbindgen --config $(abs_top_srcdir)/rust/htp/cbindgen.toml \
		--quiet --verify --output $(abs_top_builddir)/rust/gen/htp/htp_rs.h || true
else
gen/htp/htp_rs.h:
endif

doc:
	CARGO_HOME=$(CARGO_HOME) $(CARGO) doc --all-features --no-deps

if HAVE_CBINDGEN
dist/rust-bindings.h:
	$(CBINDGEN) --config $(abs_top_srcdir)/rust/cbindgen.toml \
		--quiet --output $(abs_top_builddir)/rust/dist/rust-bindings.h
else
dist/rust-bindings.h:
endif

if HAVE_CBINDGEN
dist/htp/htp_rs.h:
	cd $(abs_top_srcdir)/rust/htp && \
	cbindgen --config cbindgen.toml \
		--quiet --output $(abs_top_builddir)/rust/dist/htp/htp_rs.h
else
dist/htp/htp_rs.h:
endif

Cargo.toml: Cargo.toml.in

update-lock: Cargo.toml
	cargo update
	mv Cargo.lock Cargo.lock.in
